home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Developer / BBFig / Source / BBox.psw < prev    next >
Text File  |  1992-01-09  |  14KB  |  700 lines

  1. /* BBox.psw -- pswrap for bb.ps by Bernie Cosell  [cosell@bbn.com]
  2.     and a wrap to get back the final BoundingBox info from bb.ps.
  3.    When a new (and better) version of bb.ps becomes available,
  4.     replace the content of SendBBfig() with it with the following
  5.     changes:
  6. [1] Comment out "init" near the end of the new definition of "showpage"
  7.     operator.
  8.     
  9.    Izumi Ohzawa, 92-1-4
  10.        First wrapping
  11. */
  12.  
  13. /* bbfig.ps -- the whole thing as a pswrap */
  14.  
  15. defineps SendBBfig ()
  16. % ------- Insert new version of bb.ps below unmodified ---------------------
  17. %! 
  18. % bb.ps --
  19. % Prints a file, but keeps track of bounding box info, and prints the box at
  20. % the end (around the figure.)
  21. % $Header: bb.ps,v 1.14 91/03/21 13:04:02 cosell Exp $
  22. % RCS log info at end
  23.  
  24. 50 dict /$BoundingBox exch def
  25.  
  26. $BoundingBox begin
  27.  
  28. /xdef {
  29.     exch def
  30. } def
  31.  
  32. /xstore {
  33.     exch store
  34. } def
  35.  
  36. /addcoords {
  37.     exch
  38.     4 -1 roll add
  39.     3 1 roll add
  40. } def
  41.  
  42. % Stubs of old functions.
  43.  
  44. /-stroke /stroke load def
  45. /-fill /fill load def
  46. /-eofill /eofill load def
  47. /-image /image load def
  48. /-show /show load def
  49. /-awidthshow /awidthshow load def
  50. /-showpage /showpage load def
  51. /-restore  /restore load def
  52. /-imagemask /imagemask load def
  53.  
  54. end % $BoundingBox
  55.  
  56. % New Functions.   --- These go into the user dict to intercept the calls
  57.  
  58. /stroke {
  59.         $BoundingBox begin
  60.     gsave
  61.     initmatrix
  62.     (stroke called\n) traceprint %%DEBUG
  63.     {
  64.          strokepath    % Make sure to take line width into account.
  65.         0 setlinejoin
  66.         flattenpath
  67.     } stopped {        % strokepath often hits a limitcheck.
  68.         (Can't set up a strokepath\n) traceprint % DEBUG
  69.         grestore    % Restore the original path
  70.         gsave
  71.     } if
  72.     includepath            % Accumulate it into our box.
  73.     grestore
  74.  
  75.     -stroke
  76.     end % $BoundingBox
  77. } def
  78.  
  79. /fill {
  80.         $BoundingBox begin
  81.     gsave
  82.     (fill called\n) traceprint %%DEBUG
  83.     includepath
  84.     grestore
  85.  
  86.     -fill
  87.     end % $BoundingBox
  88. } def
  89.  
  90. /eofill {
  91.         $BoundingBox begin
  92.     gsave
  93.     (eofill called\n) traceprint %%DEBUG
  94.     includepath
  95.     grestore
  96.  
  97.     -eofill
  98.     end % $BoundingBox
  99. } def
  100.  
  101. % Text is implemented by reducing everything to an `awidthshow'.
  102.  
  103. /show {
  104.         $BoundingBox begin
  105.     (show called\n) traceprint %%DEBUG
  106.     0 0 0 0 0        % Extra parameters for awidthshow
  107.     6 -1 roll        % Bring the string back up
  108.     awidthshow
  109.     end % $BoundingBox
  110. } def
  111.  
  112. /widthshow {
  113.         $BoundingBox begin
  114.         (widthshow called\n) traceprint %%DEBUG
  115.     0 0            % Extra parameters for awidthshow
  116.     3 -1 roll        % Bring the string back up.
  117.     awidthshow
  118.     end % $BoundingBox
  119. } def
  120.  
  121. /ashow {
  122.         $BoundingBox begin
  123.         (ashow called\n) traceprint %%DEBUG
  124.     0 0 0 
  125.     6 3 roll
  126.     awidthshow
  127.     end % $BoundingBox
  128. } def
  129.  
  130.  
  131. % This does all of the work of the text-rendering operators
  132. %   What it does, is compute, basically brute force, what 'charpath'
  133. %   would have given us virtually for free, if 'show' were the only
  134. %   operator that we needed to do.
  135.  
  136. /awidthshow {
  137.     $BoundingBox begin
  138.     gsave
  139.     6 (awidthshow:) debug %%DEBUG
  140.     currentpoint
  141.     2 copy /@starty xdef /@startx xdef
  142.     2 index stringwidth    % Get the natural length of the string
  143.     addcoords            % Add to the start to get the end.
  144.  
  145.     2 index length        % How many characters?
  146.  
  147.     dup            % Add the offsets to each character
  148.     6 index mul
  149.     exch 5 index mul
  150.     addcoords
  151.  
  152.     5 index 3 index
  153.     chcount        % How many padding characters?
  154.  
  155.     dup            % Add the offsets for each pad.
  156.     9 index mul
  157.     exch 8 index mul
  158.     addcoords
  159.  
  160.     /@endy xdef /@endx xdef
  161.  
  162.     % We now have the left and right edges (in user coords)
  163.     % of the text.  Now we need only correct for the vertical
  164.     % displacements needed for the font and we can get the
  165.     % top and bottom edges of the enclosing box
  166.  
  167.     fontheight        % Get the height and depth of the current font.
  168.     
  169.     @startx @starty addcoords
  170.     /@starty xdef /@startx xdef
  171.     @endx @endy addcoords
  172.     /@endy xdef /@endx xdef
  173.     newpath
  174.     @startx @starty moveto
  175.     @endx @starty lineto
  176.     @endx @endy lineto
  177.     @startx @endy lineto
  178.     closepath
  179.         includepath
  180.     grestore
  181.  
  182.     -awidthshow
  183.     end % $BoundingBox
  184. } def
  185.  
  186. % `image':
  187. % Assume here that the image lands in the unit square.
  188.  
  189. /image {
  190.         $BoundingBox begin
  191.         (image called\n) traceprint %%DEBUG
  192.     gsave
  193.     newpath
  194.     0 0 moveto
  195.     1 0 rlineto
  196.     1 1 rlineto
  197.     -1 0 rlineto
  198.     closepath
  199.     includepath
  200.     grestore
  201.  
  202.     -image
  203.     end % $BoundingBox
  204. } def
  205.  
  206. /imagemask
  207. {
  208.     $BoundingBox begin
  209.     (imagemask called\n) traceprint %%DEBUG
  210.     gsave
  211.     newpath
  212.     0 0 moveto
  213.     1 0 rlineto
  214.     1 1 rlineto
  215.     -1 0 rlineto
  216.     closepath
  217.     includepath
  218.     grestore
  219.  
  220.     -imagemask
  221.     end % $BoundingBox
  222. } def
  223.  
  224. % Just define this one out of existence
  225. /framedevice { pop pop pop pop } def
  226.  
  227. % Handle restoring VM --- this is all OK, except that we have to
  228. % hang onto the bb info we collected while in the about-to-be-discarded
  229. % environment
  230.  
  231. /restore
  232. {
  233.     $BoundingBox begin
  234.     (restore called\n) traceprint %%DEBUG
  235.     tracedump  %% HACK, but the only way I see right now to get this stuff!
  236.     bbox-llx bbox-lly bbox-urx bbox-ury 
  237.     5 -1 roll
  238.     -restore
  239.     /bbox-ury xstore /bbox-urx xstore
  240.     /bbox-lly xstore /bbox-llx xstore
  241.     end % $BoundingBox
  242. } def
  243.  
  244.     
  245. % `showpage':
  246. % Just draw the box around the figure and print the page, and then initialize
  247. % the bounding box variables again.
  248.  
  249. $BoundingBox begin
  250. /temp-string 10 string def
  251. end % $BoundingBox
  252.  
  253. /showpage {
  254.     $BoundingBox begin
  255.     initgraphics
  256.  
  257.         (showpage\n) traceprint % DEBUG
  258.     dump-bbox  % DEBUG
  259.  
  260.         /bbox-llx round_down
  261.     /bbox-lly round_down
  262.     /bbox-ury round_up
  263.     /bbox-urx round_up
  264.  
  265.     bbox-llx bbox-lly moveto        % Make the box
  266.     bbox-llx bbox-ury lineto
  267.     bbox-urx bbox-ury lineto
  268.     bbox-urx bbox-lly lineto
  269.     closepath
  270.  
  271.     bwstroke            % Draw the box.
  272.  
  273. % Print the size of the bounding box both above and below the actual box
  274. % This has been disabled for NeXT BBFig [Izumi]
  275. %    0 setgray
  276. %    /Courier findfont 10 scalefont setfont
  277. %    bbox-llx 36 max bbox-lly 12 sub 36 max moveto
  278. %    (%%BoundingBox: ) -show
  279. %    bbox-llx temp-string cvs -show ( ) -show
  280. %    bbox-lly temp-string cvs -show ( ) -show
  281. %    bbox-urx temp-string cvs -show ( ) -show
  282. %    bbox-ury temp-string cvs -show
  283.  
  284. %    bbox-llx 36 max bbox-ury 12 add 740 min moveto
  285. %    (%%BoundingBox: ) -show
  286. %    bbox-llx temp-string cvs -show ( ) -show
  287. %    bbox-lly temp-string cvs -show ( ) -show
  288. %    bbox-urx temp-string cvs -show ( ) -show
  289. %    bbox-ury temp-string cvs -show
  290.  
  291. %    init
  292.     -showpage
  293.     tracedump        %% DEBUG
  294.     end % $BoundingBox
  295. } def
  296.  
  297. % BoundingBox functions:
  298. % We accumulate the information about the bounding box into four variables.
  299. % The data is stored in default coordinates.
  300.  
  301. $BoundingBox begin
  302.  
  303. /init {
  304.     /bbox-llx 99999 store
  305.     /bbox-lly 99999 store
  306.     /bbox-urx -99999 store
  307.     /bbox-ury -99999 store
  308. } def
  309.  
  310. /bbox-llx 0 def
  311. /bbox-lly 0 def
  312. /bbox-urx 0 def
  313. /bbox-ury 0 def
  314.  
  315. % - `includepath' -
  316. % Incorporates the bounding box of the path into the bounding box info.
  317. %   ... Gets the bounding box in default coords
  318.  
  319. /includepath {
  320.         (Adding a path: ) traceprint %%DEBUG
  321.     gsave
  322.         initmatrix
  323.     {
  324.         0 setlinejoin
  325.         flattenpath
  326.     } stopped {
  327.         (Couldn't flatten the path\n) traceprint % DEBUG
  328.         grestore
  329.         gsave
  330.         initmatrix
  331.     } if
  332.     { pathbbox } stopped not
  333.     {
  334.             4 2 roll    % Just so we get lower-left first
  335.         2 copy dump-coord %%DEBUG
  336.         dup bbox-lly lt {    
  337.             /bbox-lly xstore
  338.         } {
  339.             pop
  340.         } ifelse
  341.         dup bbox-llx lt {
  342.             /bbox-llx xstore
  343.         } {
  344.             pop
  345.         } ifelse
  346.  
  347.         (; ) traceprint 2 copy dump-coord (\n) traceprint %%DEBUG
  348.         dup bbox-ury gt {
  349.             /bbox-ury xstore
  350.         } {
  351.             pop
  352.         } ifelse
  353.         dup bbox-urx gt {
  354.             /bbox-urx xstore
  355.         } {
  356.             pop
  357.         } ifelse
  358.         dump-bbox  %%DEBUG
  359.     } if
  360.     grestore
  361. } def
  362.  
  363. % A nice black-and white line drawing function.
  364.  
  365. /bwstroke {
  366.     0 setlinewidth            % Thinnest possible lines
  367.     1 setgray            % White first
  368.     [5] 0 setdash            % Only half the line
  369.     gsave -stroke grestore
  370.     0 setgray            % Then black
  371.     [5] 5 setdash            % On the other half
  372.     -stroke
  373. } def
  374.  
  375. % Stuff for text.
  376.  
  377. % char-code string `chcount' occurs
  378. % Counts the number of times a character appears in a string.
  379.  
  380. /chcount {
  381.     0 exch
  382.     {
  383.         2 index eq {
  384.             1 add
  385.         } if
  386.     } forall
  387.     exch pop
  388. } def
  389.  
  390. % - `fontheight' heightx heighty depthx depthy
  391. % Returns the offsets to the lowest point and highest point in the current
  392. % font.
  393.  
  394. /fontheight {
  395.     currentfont begin
  396.     /FontBBox load aload pop
  397.     exch pop 0 exch
  398.     FontMatrix transform
  399.     4 2 roll
  400.     exch pop 0 exch
  401.     FontMatrix transform
  402.     end
  403. } def
  404.  
  405. % key round_{down|up} -  These will round the value of the given key
  406. %                         up or down, as appropriate, to the nearest integer
  407. /round_up   { dup load ceiling cvi store } def
  408. /round_down { dup load floor   cvi store } def
  409.  
  410. % key binddefinition - this will do a 'bind' on the procedure given by 'key'
  411. /binddefinition
  412. {
  413.     dup where
  414.     {  
  415.         exch
  416.         2 copy
  417.         get bind put
  418.     }     
  419.     { undefined } ifelse
  420. } def  
  421.  
  422. % Given two numbers on the stack, return with just the smallest
  423. /min { 2 copy ge { exch } if pop } def
  424.  
  425. % Dito for the largest of the pair
  426. /max { 2 copy lt { exch } if pop } def
  427.  
  428.  
  429. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
  430. %
  431. %   Debugging utilities
  432. %
  433.  
  434. /$tracedict where
  435. {  % Trace package loaded... do the tracing
  436.     pop
  437. % This is a debugging function to print out what is going on.
  438. %  Format <argn> <argn-1> ... <arg1> n <string> debug <argn> ... <arg1>
  439. %    (that is, the 'n' args will be *left* on the stack!)
  440. /debug
  441. {
  442.     traceprint (\n) traceprint 
  443.     dup 1 add   % Now total number of args (including arg count) 
  444.     copy
  445.     {
  446.         (    ) traceprint 
  447.     trace=
  448.         (\n) traceprint
  449.     } repeat
  450.     pop    % Remove the extra copy of the arg count
  451. } def
  452.  
  453. % Print out a coordinate on the stack:  x y --- 
  454. /dump-coord
  455. {
  456.     (\() traceprint exch trace= (, ) traceprint trace= (\)) traceprint
  457. } def
  458.  
  459. % Print out bb's current notion of its bounding box
  460.  
  461. /dump-bbox
  462. {
  463.     (Bounding Box: ) traceprint
  464.     bbox-llx bbox-lly dump-coord
  465.     (; ) traceprint
  466.     bbox-urx bbox-ury dump-coord
  467.     (\n) traceprint
  468. } def
  469.  
  470. tracebegin %% DEBUG
  471.  
  472. }
  473. { % No trace package loaded, so don't trace.  Stub out the various calls
  474.  
  475. /traceprint { pop } def
  476. /dump-coord { pop pop } def
  477. /dump-bbox { } def
  478. /debug { pop  pop } def
  479. /tracedump { } def
  480.  
  481. } ifelse
  482.  
  483. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
  484.  
  485. % Bind everything
  486.  
  487. /xdef binddefinition
  488. /xstore binddefinition
  489. /addcoords binddefinition
  490. /stroke binddefinition
  491. /fill binddefinition
  492. /eofill binddefinition
  493. /show binddefinition
  494. /widthshow binddefinition
  495. /ashow binddefinition
  496. /awidthshow binddefinition
  497. /image binddefinition
  498. /showpage binddefinition
  499. /init binddefinition
  500. /includepath binddefinition
  501. /bwstroke binddefinition
  502. /chcount binddefinition
  503. /fontheight binddefinition
  504.  
  505. /debug binddefinition
  506. /dump-coord binddefinition
  507. /dump-bbox binddefinition
  508.  
  509. % Start it up.
  510.  
  511. init
  512.  
  513. end % $BoundingBox
  514.  
  515. %  end of bb.ps
  516.  
  517. % $Log:    bb.ps,v $
  518. % Revision 1.14  91/03/21  13:04:02  cosell
  519. % Relocated the position of the constrained BBox info
  520. % Revision 1.13  91/03/21  12:21:04  cosell
  521. % Forced the %BoundingBox info to stay within the page boundaries
  522. % Revision 1.12  91/03/21  12:15:17  cosell
  523. % Added a tracing hook to bridge restores.
  524. % Revision 1.11  90/07/02  08:48:40  cosell
  525. % bbfig now correctly copes with empty paths
  526. % Revision 1.10  90/06/27  10:47:22  cosell
  527. % Added a bunch of improvements from Joe Pallas at stanford.
  528. % Revision 1.9  90/06/26  10:50:20  cosell
  529. % Stack got botched in the 'debug' stub
  530. % Revision 1.8  90/06/25  09:34:51  cosell
  531. % Minor bug in 'restore'
  532. % Revision 1.7  90/06/25  09:29:58  cosell
  533. % Added code to catch and deal with 'restore'.  Thanks to Frank
  534. % Jensen for finding this one
  535. % Revision 1.6  90/06/25  09:23:26  cosell
  536. % Small bugfix in the text-handling stuff
  537. % Revision 1.5  90/06/10  09:04:02  cosell
  538. % Changed the printed string to explictly say "%%BoundingBox"
  539. % Revision 1.4  90/06/10  08:55:39  cosell
  540. % Added 'bind' machinery to insulate this package from later redefinitions
  541. % of things we need from the systemdict.
  542. % Revision 1.3  90/06/10  08:28:53  cosell
  543. % Added debugging hooks.  They don't affect anything (and don't do
  544. % anything) in the normal use of bbfig.  But if the 'trace' package
  545. % is loaded ahead of this, it'll print out some helpful info.  Probably
  546. % I'll end up removing all of this if/when I really get the package
  547. % up to snuff.
  548. % Revision 1.2  90/05/25  12:08:24  cosell
  549. % Major improvements and tuneups:  fixed it to really use its private
  550. % discionary, and the most importnat: it now computes the bounding box
  551. % in *default* coords
  552. %
  553. % Revision 1.1  90/05/23  08:18:54  cosell
  554. % Initial revision
  555. %   This is Ned Bachelder's original version
  556. % ------- Insert new version of bb.ps above -----------------------------
  557. endps  /* of SendBBfig () */
  558.  
  559.  
  560.  
  561. /* pswrap to get the final BoundingBox info back. */
  562. defineps GetBBox (|float *llx, *lly, *urx, *ury)
  563.     $BoundingBox begin
  564.     bbox-llx llx bbox-lly lly bbox-urx urx bbox-ury ury
  565.     end % $BoundingBox
  566. endps
  567.  
  568.  
  569.  
  570. /* ShowMesh() -- Jan. 10, 1992  Izumi Ohzawa  -- First version */
  571.  
  572. defineps ShowMesh()
  573.  
  574. % /yapwidth 612 def        % already defined
  575. % /yapheight 792 def
  576.  
  577. /temp-str 10 string def
  578. /Helvetica findfont 10 scalefont setfont
  579.  
  580. % First Horizontal lines
  581. 0.66667 setgray
  582. % [2 2] 0 setdash
  583.  
  584. 0 10 yapheight
  585. {
  586.   % y on stack
  587.   dup    % y y 
  588.   0 exch moveto    % y 
  589.   yapwidth exch lineto    %  y
  590.   stroke
  591. } for
  592.  
  593. % [] 0 setdash
  594.  
  595. 0.3333 setgray
  596.  
  597. 0 100 yapheight
  598. {
  599.   % y on stack
  600.   dup dup    % y y y
  601.   0 exch moveto    % y y
  602.   gsave
  603.   3 1 rmoveto
  604.   dup temp-str cvs show
  605.   grestore
  606.   yapwidth exch lineto    %  y
  607.   gsave
  608.   stroke
  609.   grestore
  610.   -20 2 rmoveto
  611.   temp-str cvs show
  612.   newpath
  613. } for
  614.  
  615.  
  616. % now do vertical lines
  617. gsave
  618. 0 yapheight translate -90 rotate
  619.  
  620. 0.66667 setgray
  621. % [2 2] 0 setdash
  622.  
  623. 10 10 yapwidth
  624. {
  625.   % y on stack
  626.   dup    % y y
  627.   0 exch moveto    % y
  628.   yapheight exch lineto
  629.   stroke
  630. } for
  631.  
  632. % [] 0 setdash
  633.  
  634. 0.3333 setgray
  635.  
  636. 100 100 yapwidth
  637. {
  638.   % y on stack
  639.   dup dup    % y y y
  640.   0 exch moveto    % y y
  641.   gsave
  642.   5 1 rmoveto
  643.   dup temp-str cvs show
  644.   grestore
  645.   yapheight exch lineto    %  y
  646.   gsave
  647.   stroke
  648.   grestore
  649.   -18 2 rmoveto
  650.   temp-str cvs show
  651.   newpath
  652. } for
  653.  
  654. grestore  % rotation and translation for vertical lines
  655. 0 setgray
  656.  
  657. endps  /* of ShowMesh() */
  658.  
  659.